#include "microbe_ai.h"

#include <common.h>

////////////////////////////////////////////////////////////////////////////////

ExampleAI::ExampleAI()
{
  state.type = EXAMPLE_STATE_NORMAL;
}

void ExampleAI::think(const AIData& data, MicrobeOrder* order[SIM_MAX_MICROBES],
  int dM, float dT)
{
  transitionState(data);
  executeState(data, order);
}

void ExampleAI::transitionState(const AIData& data)
{
  const Rectf& bounds = data.bounds;
  const Microbe* microbe = data.microbe[0];
  const Vector2& pos = microbe->body.pos;
  const float angle = microbe->angle;
  const float safety_dis = 48.0f;
  
  if (state.type == EXAMPLE_STATE_NORMAL)
  {
    if (pos.x - bounds.min_x < safety_dis && angle > 90.0f && angle < 270.0f)
    {
      state.type = EXAMPLE_STATE_AVOID_WALL;
      state.angle = Math_angleWrap360(Rand_float(-80.0f, 80.0f));
    }
    else if (pos.y - bounds.min_y < safety_dis && angle > 180.0f && angle < 360.0f)
    {
      state.type = EXAMPLE_STATE_AVOID_WALL;
      state.angle = Rand_float(10.0f, 170.0f);
    }
    else if (bounds.max_x - pos.x < safety_dis && (angle < 90.0f || angle > 270.0f))
    {
      state.type = EXAMPLE_STATE_AVOID_WALL;
      state.angle = Rand_float(100.0f, 260.0f);
    }
    else if (bounds.max_y - pos.y < safety_dis && angle > 0.0f && angle < 180.0f)
    {
      state.type = EXAMPLE_STATE_AVOID_WALL;
      state.angle = Rand_float(190.0f, 350.0f);
    }
  }
  else if (state.type == EXAMPLE_STATE_AVOID_WALL)
  {
    if (Math_angleCmp(microbe->angle, state.angle, 3.0f))
    {
      state.type = EXAMPLE_STATE_NORMAL;
    }
  }
}

void ExampleAI::executeState(const AIData& data,
  MicrobeOrder* order[SIM_MAX_MICROBES])
{
  const Microbe* microbe = data.microbe[0];
  
  if (state.type == EXAMPLE_STATE_NORMAL)
  {
    order[0]->turn = 0.0f;
  }
  else if (state.type == EXAMPLE_STATE_AVOID_WALL)
  {
    if (Math_angleWrap180(microbe->angle - state.angle) > 0.0f)
    {
      order[0]->turn = -1.0f;
    }
    else
    {
      order[0]->turn = 1.0f;
    }
  }
}

////////////////////////////////////////////////////////////////////////////////

AI* AI_create()
{
  return new ExampleAI();
}
